package com.gin.kotlin.no_gay_alliance.fragment.pm

import android.content.res.Configuration
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import androidx.annotation.DrawableRes
import androidx.core.graphics.drawable.toBitmap
import com.gin.kotlin.no_gay_alliance.R
import com.gin.kotlin.no_gay_alliance.activity.pm.PrivateMessageReplyActivity
import com.gin.kotlin.no_gay_alliance.app.App
import com.gin.kotlin.no_gay_alliance.argument.PrivateMessageReplyArgument
import com.gin.kotlin.no_gay_alliance.databinding.FragmentPrivateMessagePageAbstractBinding
import com.gin.kotlin.no_gay_alliance.enums.NgaTheme
import com.gin.kotlin.no_gay_alliance.fragment.replylist.ReplyPageHtmlFragment.Companion.bitmapToBase64
import com.gin.kotlin.no_gay_alliance.store.GlobalProperty
import com.gin.kotlin.no_gay_alliance.utils.TimeUtils.Companion.DATE_TIME_FORMATTER_MONTH_SECOND
import com.gin.kotlin.no_gay_alliance.utils.TimeUtils.Companion.FULL_DATE_TIME_FORMATTER
import com.gin.kotlin.no_gay_alliance.webview.BbsCodeWebView
import com.gin.nga.enums.status.AccountStatus
import com.gin.nga.response.message.PriMsgReply
import com.gin.nga.response.message.PriMsgReplyData
import com.gin.nga.utils.BbsCodeRenderer
import com.gin.nga.utils.StrUtils
import java.time.ZonedDateTime

/**
 * 以单页HTML渲染的一页私信回复
 * @property renderer 正文渲染器
 * @property replyTemplate 单个回复的模板
 * @property template 整个页面的模板
 * @property webView BbsCodeWebView
 */
class PrivateMessageReplyHtmlFragment : AbstractPrivateMessageReplyPageFragment() {
    private lateinit var renderer: BbsCodeRenderer
    private lateinit var replyTemplate: String
    private lateinit var template: String
    private lateinit var webView: BbsCodeWebView

    override fun onDestroyView() {
        super.onDestroyView()

        (this.webView.parent as? ViewGroup)?.removeAllViews()
        this.webView.busy = false
        this.webView.loadDataWithBaseURL("")
    }

    override fun onSuccess(data: PriMsgReplyData) {

        val replies = data.data

        val globalProperty = GlobalProperty.getInstance()
        // 系统当前是否处于深色模式
        val systemUiModeNight = resources.configuration.uiMode.and(Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
        // 系统当前主题
        val theme = if (systemUiModeNight && globalProperty.themeFollow) NgaTheme.BLACK else globalProperty.theme
        // 回复列表的渲染结果
        val containers = renderReplies(replies,theme)
        // 整个页面的渲染结果
        val html = template.replace("[根CLASS占位]", "").replace("[回复容器占位]", containers)

        this.webView.loadDataWithBaseURL(html)



    }

    private fun renderReplies(replies: List<PriMsgReply>?, theme: NgaTheme): String {
        // 查询用户IP属地
        val ipLocationHistoryDao = App.INSTANCE.database.ipLocationHistoryDao()
        val ipMap = replies?.mapNotNull { it.userId }?.toTypedArray()
            ?.let { ipLocationHistoryDao.queryLastIdByUserId(it) }
            ?.let { ipLocationHistoryDao.queryById(it.toTypedArray()) }
            ?.associate { Pair(it.userId, it.location) } ?: mapOf()

        return replies?.withIndex()?.joinToString (""){ indexedValue ->
            val index = indexedValue.index
            val light = index % 2 ==0
            val dataModel = indexedValue.value

            // 背景颜色
            val bgcClass = when (theme) {
                NgaTheme.YELLOW -> if (light) "background_color_yellow_light" else "background_color_yellow_dark"
                NgaTheme.GREEN -> if (light) "background_color_green_light" else "background_color_green_dark"
                NgaTheme.BLACK -> if (light) "background_color_black_light" else "background_color_black_dark"
            }

            // 容器class，如果是沃顿显示沃顿蓝
            val containerClass = if (theme == NgaTheme.BLACK) "black_text_color" else "default_text_color"
            // 正文字体颜色
            val contentClass =if (theme == NgaTheme.BLACK) "black_text_color" else "default_text_color"
            // 头像
            val avatar = dataModel.userInfo?.getAvatars()?.get(0) ?:obtainImgByDrawableId(R.drawable.ic_person_18) ?: ""

            val time = dataModel.timestamp?.format(if (ZonedDateTime.now().year == dataModel.timestamp?.year) DATE_TIME_FORMATTER_MONTH_SECOND else FULL_DATE_TIME_FORMATTER) ?: ""

            replyTemplate
                .replace("{标题占位}", StrUtils.escape(dataModel.title) ?: "")
                .replace("{IP属地}", ipMap[dataModel.userId] ?: "")
                .replace("{userId}", dataModel.userId.toString())
                .replace("{账号状态占位}", dataModel.userInfo?.getAccountStatus()?.let {
                    when (it) {
                        AccountStatus.PHONE, AccountStatus.LINK -> ""
                        else -> "<span style='color:${it.color}'>[${it.cn}]</span>"
                    }
                } ?: "")
                .replace("{正文占位}", renderer.render(dataModel.getBbsCodeNode()) ?: "")
                .replace("{背景色CLASS占位}", bgcClass)
                .replace("{容器CLASS占位}", containerClass)
                .replace("{正文CLASS}", contentClass)
                .replace("{用户名占位}", dataModel.userInfo?.username?:"#系统账号#")
                .replace("{头像占位}", avatar)
                .replace("{发布时间占位}", time)
        }?:""
    }

    override fun onError() {
        this.webView.visibility = View.GONE
    }

    override fun initRenderComponent(binding: FragmentPrivateMessagePageAbstractBinding) {
        this.webView = (requireActivity() as PrivateMessageReplyActivity).bbsCodeWebViewPool.obtainWebView()
            .also { it.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) }

        binding.swipeRefreshLayout.addView(this.webView)
        this.template = requireContext().assets.open("template.html").bufferedReader().readText()
        this.replyTemplate = requireContext().assets.open("private_reply_template.html").bufferedReader().readText()
        this.renderer = BbsCodeRenderer(GlobalProperty.getInstance().domain, App.INSTANCE.emoteGroup)
    }

    /**
     * 将drawable转换为base64
     * @param drawableId Int
     * @return String?
     */
    private fun obtainImgByDrawableId(@DrawableRes drawableId: Int) = getDrawable(drawableId)?.toBitmap()?.let { "data:image/png;base64,${bitmapToBase64(it)}" }

    companion object {
        fun newInstance(argument: PrivateMessageReplyArgument): PrivateMessageReplyHtmlFragment {
            val args = Bundle()
            args.putParcelable(PrivateMessageReplyArgument::class.java.simpleName, argument)
            val fragment = PrivateMessageReplyHtmlFragment()
            fragment.arguments = args
            return fragment
        }


    }
}